home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 187_01 / vbar.c < prev    next >
C/C++ Source or Header  |  1986-01-19  |  5KB  |  161 lines

  1.  
  2. /*@******************************************************************
  3.  *@ 
  4.  *@  VBAR generates a vertical bar graph from a pair of vectors.
  5.  *@
  6.  *@  vbar(x, y, num, title, xtitle, ytitle, maxrows, maxcols, xdec, ydec)
  7.  *@
  8.  *@ where:
  9.  *@        x         - vector of x coordinates
  10.  *@        y         - vector of y coordinates
  11.  *@        num     - number of elements in both x and y
  12.  *@        title    - graph title (printed at top of page)
  13.  *@        xtitle    - title of x coordinate (printed at bottom-horizontal)
  14.  *@        ytitle    - title of y coordinate (printed at left side-horizontally)
  15.  *@        maxrows - maximum number of y lines to be printed
  16.  *@        maxcols - maximum number of x lines to be printed
  17.  *@        xdec    - number of decimal places in x values
  18.  *@        ydec    - number of decimal places in y values
  19.  *@
  20.  *@******************************************************************** */
  21.  
  22.  
  23. #define    YTICKW    16            /* y tick width */
  24.  
  25. int vbar(x, y, num, title, xtitle, ytitle, maxrows, maxcols, xdec, ydec)
  26. int *x, *y, num, maxrows, maxcols, xdec, ydec;
  27. char *title, *xtitle, *ytitle;
  28. {
  29.     char mytitle[80], pad[80], c[2], strbuf[80];
  30.     char *r_just(), *itoa(), *c_just(), *p, *mak_dec();
  31.     int i, j, xmax, xmin, ymax, ymin, xinc, yinc;
  32.     int xbuck, xbuckv, ybuck, ybuckv, yval, xrange, yrange;
  33.     int gutter, xwide, ywide, temp, k, lower, upper, r, l;
  34.  
  35.     gutter = 1;        /* dist between bars */
  36.     maxcols -= YTICKW;    /* subtract y-tick width */
  37.     xmax = xmin = x[0];   
  38.     ymax = ymin = y[0];   
  39.  
  40.     for (i=0; i < num; i++) {    /* determine x and y data ranges */
  41.         if (xmax < x[i])
  42.             xmax = x[i];
  43.         if (ymax < y[i])
  44.             ymax = y[i];
  45.         if (xmin > x[i])
  46.             xmin = x[i];
  47.         if (ymin > y[i])
  48.             ymin = y[i];
  49.     }
  50.  
  51.     /* compute the x and y bucket sizes */
  52.     xrange = xmax - xmin;
  53.     yrange = ymax - ymin;
  54.     for (i=1; i < (maxcols - 2); i++) {
  55.         xbuck = maxcols / (gutter + i);        /* i is size of one bucket */
  56.         xinc = (xrange + xbuck - 1) / xbuck;
  57.         if (xinc >= 1)            /* continue until you fill the avail space */
  58.             break;
  59.     }
  60.     xwide = i;
  61.     if (xinc < 1) {
  62.         xbuck = maxcols / (gutter + 1);
  63.         xinc = 1;
  64.     }
  65.     else
  66.         xbuck = (xrange + xinc - 1) / xinc;        /* readjust buckets, if necessary */
  67.     
  68.     for (i=1; i < maxrows; i++) {
  69.         ybuck = maxrows / i;
  70.         yinc = (yrange + ybuck - 1) / ybuck;
  71.         if (yinc >= 1)
  72.             break;
  73.     }
  74.     ywide = i;
  75.     if (yinc < 1) {
  76.         ybuck = maxrows;
  77.         yinc = 1;
  78.     }
  79.     else
  80.         ybuck = (yrange + yinc - 1) / yinc;        /* readjust buckets, if necessary */
  81.     
  82.  
  83.     /* compute pad on left of graph to center graph horizontally */
  84.     temp = maxcols - xbuck * (xwide + gutter);
  85.     for (i=0; i < temp;)
  86.         pad[i++] = ' ';
  87.     pad[i] = '\0';
  88.  
  89.     /* print the graph title at the top  */
  90.     puts("\n\n\n");
  91.     for (i=0; i < YTICKW; i++)
  92.         puts(" ");
  93.     puts(c_just(title, xbuck * (gutter + xwide)));
  94.     puts("\n\n");
  95.  
  96.     /* print the y-axis title at the left of the page */
  97.     puts("    ");
  98.     puts(ytitle);
  99.     puts("\n");
  100.  
  101.     /* draw the chart */
  102.     c[1] = '\0';    /* set EOS */
  103.     for (i=0; i < ybuck; i++) {    /* once per line (y buckets) */
  104.         yval = ymax - (i * yinc);
  105.         puts("\n  ");
  106.         puts(r_just(mak_dec(itoa(yval, strbuf), ydec), 10));
  107.         puts("  |");
  108.         for (j=1; j <= xbuck; j++) {    /* once per column (x buckets) */
  109.             temp = 0;
  110.             lower = (j-1) * xinc;        /* compute proper x-range */
  111.             upper = lower + xinc;
  112.             r = 0;
  113.             for (k=0; k < num; k++)        /* sum all y values in this x-range */
  114.                 if ((x[k] > lower) && (x[k] <= upper)) {
  115.                     temp += y[k];
  116.                     r++;        /* indicate that at least one was found */
  117.                 }
  118.             if ((temp >= yval) && r)     /* if in range and at least one hit */
  119.                 c[0] = '*';
  120.             else
  121.                 c[0] = ' ';
  122.             for (k=0; k < gutter; k++)
  123.                 puts(" ");
  124.             for (k=0; k < xwide; k++)
  125.                 puts(c);
  126.         }
  127.     }
  128.     puts("\n");
  129.  
  130.     /* print the x-scale */
  131.     puts("              |\b__");    /* skip to start of Y axis */
  132.     for (i=0; i <= xbuck; i++)
  133.         for (k=0; k < (gutter + xwide); k++)
  134.             puts("_");
  135.     puts("\n");
  136.     for (i=1; i < YTICKW; i++)    /* skip to start of Y axis */
  137.         puts(" ");
  138.     temp = xinc + xmin;
  139.     while (temp <= xmax) 
  140.         for (r=1; r > 0; r++, temp += xinc) {
  141.             itoa(temp, strbuf);
  142.             if (xdec)            /* suppress decimal point if zero decimal places */
  143.                 l = strlen(p = mak_dec(strbuf, xdec));    /* make value a string */
  144.             else
  145.                 l = strlen(p = strbuf);    /* make value a string */
  146.             i = r * (gutter + xwide);
  147. /*            printf("r=%d, temp=%d, l=%d, i=%d\n", r, temp, l, i);  */
  148.             if ((i / (l + 1)) >= 1) {    /* does it fit? */
  149.                 puts(r_just(p, i));        /* yes, output it */
  150.                 r = -1;                    /* .. and quit trying */
  151.             }
  152.         }
  153.          
  154.     puts("\n");
  155.     for (i=0; i < YTICKW; i++)
  156.         puts(" ");
  157.     puts(c_just(xtitle, xbuck * (gutter + xwide)));
  158.     puts("\n");
  159. }
  160.  
  161.